use redis::{aio::Connection, AsyncCommands, Client, RedisResult};
use serde::Serialize;

#[derive(Serialize)]
pub struct KeyTypes {
    key: String,
    key_type: String,
}

/**
 * 通过 url 获取链接
 * redis://default:wl110511@139.9.241.21:6000
 */
pub async fn redis_connect(url: String) -> RedisResult<Connection> {
    // 生成客户端
    let client = Client::open(url).expect("生成Redis Client Failed");
    // 获取链接
    client.get_async_connection().await
}
/**
 * 获取所有的 keys
 */
pub async fn redis_keys(mut connect: Connection) -> RedisResult<Vec<String>> {
    let value: Vec<String> = connect.keys("*").await?;
    Ok(value)
}
/**
 * 获取 keys 和 types
 */
pub async fn redis_key_types(mut connect: Connection) -> RedisResult<Vec<KeyTypes>> {
    let mut key_types: Vec<KeyTypes> = Vec::new();
    let keys: Vec<String> = connect.keys("*").await?;
    for i_key in keys {
        let i_key_type: String = connect.key_type(&i_key).await?;
        let i_key_types = KeyTypes {
            key: i_key,
            key_type: i_key_type,
        };
        key_types.push(i_key_types);
    }
    Ok(key_types)
}

/**
 * 获取 String 类型的keys
 */
pub async fn redis_string_value(mut connect: Connection, key: String) -> RedisResult<String> {
    connect.get(key).await
}
/**
 * 获取 hash 类型的数据集
 */
pub async fn redis_hash_key_values(
    mut connect: Connection,
    key: String,
) -> RedisResult<Vec<(String, String)>> {
    let value:Vec<(Vec<u8>, Vec<u8>)>  = connect.hgetall(&key).await?;
    let result: Vec<(String, String)> = value.into_iter().map(|(vc1, vc2)| {
        let hash_key = String::from_utf8_lossy(&vc1).to_string();
        let hash_value = String::from_utf8_lossy(&vc2).to_string();
        (hash_key, hash_value)
    }).collect();
    Ok(result)
}
